home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / mus / edit / amisox_wav.lha / echo.c < prev    next >
C/C++ Source or Header  |  1992-05-01  |  5KB  |  225 lines

  1.  
  2. /*
  3.  * July 5, 1991
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11. /*
  12. **     Echo effect. based on:
  13. **
  14. ** echoplex.c - echo generator
  15. **
  16. ** Copyright (C) 1989 by Jef Poskanzer.
  17. **
  18. ** Permission to use, copy, modify, and distribute this software and its
  19. ** documentation for any purpose and without fee is hereby granted, provided
  20. ** that the above copyright notice appear in all copies and that both that
  21. ** copyright notice and this permission notice appear in supporting
  22. ** documentation.  This software is provided "as is" without express or
  23. ** implied warranty.
  24. */
  25.  
  26. /*
  27.  * Sound Tools echo effect file.
  28.  */
  29.  
  30. #include "st.h"
  31. #include <math.h>
  32.  
  33. #define FADE_THRESH 10
  34. #define MYBUFSIZ 256
  35. #define DELAYBUFSIZ ( 50 * MAXRATE )
  36. #define MAXDELAYS 30
  37.  
  38. struct echoplex {
  39.     int    counter;            
  40.     int    numdelays;
  41.     long    *delaybuf;
  42.     float    delay[MAXDELAYS], atten[MAXDELAYS];
  43.     long    samples[MAXDELAYS], maxsamples;
  44.     long    pl, ppl, pppl;
  45. };
  46.  
  47. /* Private data for SKEL file */
  48. typedef struct echostuff {
  49.     struct    echoplex *echoplex;
  50. } *echo_t;
  51.  
  52. #ifndef abs
  53.     #define abs(a) ((a) >= 0 ? (a) : -(a))
  54. #endif
  55.  
  56. long clip24();
  57.  
  58. #ifndef AMIGA        /* cared for below...weirdness of SAS */
  59. double atof();
  60. #endif
  61.  
  62. extern writing;
  63.  
  64. /*
  65.  * Process options
  66.  */
  67. echo_getopts(effp, n, argv) 
  68. eff_t effp;
  69. int n;
  70. char **argv;
  71. {
  72.     echo_t echo = (echo_t) effp->priv;
  73.     struct echoplex *e;
  74.     int i;
  75.  
  76.     echo->echoplex = (struct echoplex *) malloc(sizeof(struct echoplex));
  77.     e = echo->echoplex;
  78.     e->numdelays = 0;
  79.     e->maxsamples = 0;
  80.  
  81.     if ((n == 0) || (n & 1))
  82.         fail("Usage: echo delay attenuation [ delay attenuation ... ]");
  83.  
  84.     i = 0;
  85.     while (i < n) {
  86. #ifdef AMIGA
  87. /* since SAS C complains about uncast atof() */
  88.         e->delay[e->numdelays] = (double) atof( argv[i++] );
  89.         e->atten[e->numdelays] = (double) atof( argv[i++] );
  90. #else
  91.         e->delay[e->numdelays] = atof( argv[i++] );
  92.         e->atten[e->numdelays] = atof( argv[i++] );
  93. #endif
  94.         e->numdelays++;
  95.     }
  96. }
  97.  
  98. /*
  99.  * Prepare for processing.
  100.  */
  101. echo_start(effp)
  102. eff_t effp;
  103. {
  104.     echo_t echo = (echo_t) effp->priv;
  105.     struct    echoplex *e = echo->echoplex;
  106.     int i;
  107.  
  108.     for(i = 0; i < e->numdelays; i++) {
  109.         e->samples[i] = e->delay[i] * effp->ininfo.rate;
  110.         if ( e->samples[i] < 1 )
  111.             fail(" delay must positive, aye!");
  112.         if ( e->samples[i] > DELAYBUFSIZ )
  113.             fail("Echo: delay must be less than %g seconds",
  114.                 DELAYBUFSIZ / (float) effp->ininfo.rate );
  115.         if ( e->atten[i] < 0.0 )
  116.             fail("attenuation must positive, aye!\n" );
  117.         if ( e->samples[i] > e->maxsamples )
  118.             e->maxsamples = e->samples[i];
  119.     }
  120.     if (! (e->delaybuf = (long *) malloc(sizeof (long) * e->maxsamples)))
  121.         fail("Echo: Cannot malloc %d bytes\n", 
  122.             sizeof(long) * e->maxsamples);
  123.     for ( i = 0; i < e->maxsamples; ++i )
  124.         e->delaybuf[i] = 0;
  125.     e->pppl = e->ppl = e->pl = 0x7fffff;        /* fade-outs */
  126.     e->counter = 0;
  127. }
  128.  
  129. /*
  130.  * Processed signed long samples from ibuf to obuf.
  131.  * Return number of samples processed.
  132.  */
  133.  
  134. echo_flow(effp, ibuf, obuf, isamp, osamp)
  135. eff_t effp;
  136. long *ibuf, *obuf;
  137. int *isamp, *osamp;
  138. {
  139.     echo_t echo = (echo_t) effp->priv;
  140.     struct    echoplex *e = echo->echoplex;
  141.     int len, done;
  142.     int i, j;
  143.     
  144.     long l;
  145.  
  146.     i = e->counter;
  147.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  148.     for(done = 0; done < len; done++) {
  149.         /* Store delays as 24-bit signed longs */
  150.         l = *ibuf++ / 256;
  151.         for ( j = 0; j < e->numdelays; ++j )
  152.             l = l + 
  153. e->delaybuf[( i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  154.         l = clip24(l);
  155.         e->delaybuf[i] = l;
  156.         *obuf++ = l * 256;
  157.         i++;        /* XXX need a % maxsamples here ? */
  158.         i %= e->maxsamples;
  159.     }
  160.     e->counter = i;
  161.     /* processed all samples */
  162. }
  163.  
  164. /*
  165.  * Drain out echo lines. 
  166.  */
  167. echo_drain(effp, obuf, osamp)
  168. eff_t effp;
  169. long *obuf;
  170. long *osamp;
  171. {
  172.     echo_t echo = (echo_t) effp->priv;
  173.     struct    echoplex *e = echo->echoplex;
  174.     long l;
  175.     int i, j, done;
  176.  
  177.     i = e->counter;
  178.     done = 0;
  179.     /* drain out delay samples */
  180.     do {
  181.         l = 0;
  182.         for ( j = 0; j < e->numdelays; ++j )
  183.             l += 
  184. e->delaybuf[(i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  185.         l = clip24(l);
  186.         e->delaybuf[i] = l;
  187.         obuf[done++] = l * 256;
  188.         e->pppl = e->ppl;
  189.         e->ppl = e->pl;
  190.         e->pl = l;
  191.         i++;        /* need a % maxsamples here ? */
  192.         i %= e->maxsamples;
  193.     } while((done < *osamp) && 
  194.         ((abs(e->pl) + abs(e->ppl) + abs(e->pppl)) > FADE_THRESH));
  195.     e->counter = i;
  196.     *osamp = done;
  197.     /* drain will not be called again */
  198. }
  199.  
  200. /*
  201.  * Clean up echo effect.
  202.  */
  203. echo_stop(effp)
  204. eff_t effp;
  205. {
  206.     echo_t echo = (echo_t) effp->priv;
  207.  
  208.     free((char *) echo->echoplex);
  209.     echo->echoplex = (struct echoplex *) -1;   /* guaranteed core dump */
  210. }
  211.  
  212. long
  213. clip24(l)
  214. long l;
  215. {
  216.     if (l >= ((long)1 << 24))
  217.         return ((long)1 << 24) - 1;
  218.     else if (l <= -((long)1 << 24))
  219.         return -((long)1 << 24) + 1;
  220.     else
  221.         return l;
  222. }
  223.  
  224.  
  225.